﻿// DigitalDesign
// Project: InformationBoard
// Developer: Bobylev Dmitry
// Created: 13.11.2011
// Last change: 26.11.2011
// Description: methods of schedule page.

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using GUIAdmin.AdminServiceReference;
using System.Collections.ObjectModel;
using GUIAdmin.ScheduleServiceReference;

namespace GUIAdmin
{
    public partial class Schedule : Page
    {
        private ScheduleServiceClient scheduleClient = new ScheduleServiceClient();
        private wLocation locationTemp = new wLocation();

        public Schedule()
        {
            InitializeComponent();

            scheduleClient.SetCancelledScheduleCompleted +=
                new EventHandler<SetCancelledScheduleCompletedEventArgs>
                    (scheduleClient_SetCancelledScheduleCompleted);
            scheduleClient.DeleteScheduleChangesCompleted +=
                    new EventHandler<DeleteScheduleChangesCompletedEventArgs>
                        (scheduleClient_DeleteScheduleChangesCompleted);
            scheduleClient.DeleteScheduleCompleted +=
                    new EventHandler<DeleteScheduleCompletedEventArgs>
                        (scheduleClient_DeleteScheduleCompleted);
            scheduleClient.GetScheduleCompleted +=
                new EventHandler<GetScheduleCompletedEventArgs>
                    (scheduleClient_GetScheduleCompleted);
            scheduleClient.GetChangesScheduleCompleted +=
                new EventHandler<GetChangesScheduleCompletedEventArgs>
                    (scheduleClient_GetChangesScheduleCompleted);
            scheduleClient.GetCancelledScheduleCompleted +=
                new EventHandler<GetCancelledScheduleCompletedEventArgs>
                    (scheduleClient_GetCancelledScheduleCompleted);
            scheduleClient.GetAddedScheduleCompleted +=
                new EventHandler<GetAddedScheduleCompletedEventArgs>
                    (scheduleClient_GetAddedScheduleCompleted);
            scheduleClient.ReplaceScheduleCompleted +=
                new EventHandler<ReplaceScheduleCompletedEventArgs>
                    (scheduleClient_ReplaceScheduleCompleted);
            scheduleClient.AddScheduleCompleted +=
                    new EventHandler<AddScheduleCompletedEventArgs>
                        (scheduleClient_AddScheduleCompleted);
            scheduleClient.ReplaceScheduleChangesCompleted +=
                    new EventHandler<ReplaceScheduleChangesCompletedEventArgs>
                        (scheduleClient_ReplaceScheduleChangesCompleted);
            scheduleClient.GetLocationsCompleted +=
                new EventHandler<GetLocationsCompletedEventArgs>
                    (scheduleClient_GetLocationsCompleted);
            scheduleClient.AddScheduleChangeCompleted +=
                    new EventHandler<AddScheduleChangeCompletedEventArgs>
                        (scheduleClient_AddScheduleChangeCompleted);
        }

        // Выполняется, когда пользователь переходит на эту страницу.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            VisibilityTable(ScheduleTablePanel);
            RefreshSchedule();
        }

        #region Table Refresh

        //обновление таблицы с обычным расписанием
        private void RefreshSchedule()
        {
            if (this.DataContext != null)
                scheduleClient.GetScheduleAsync((this.DataContext as StationNotEF).Id);
        }

        //обновление таблицы с изменениями в расписании
        private void RefreshChangesSchedule()
        {
            scheduleClient.GetChangesScheduleAsync
                ((this.DataContext as StationNotEF).Id, To.SelectedDate, from.SelectedDate);
        }

        //обновление таблицы с отмененными поездами в расписании        
        private void RefreshCancelSchedule()
        {
            scheduleClient.GetCancelledScheduleAsync
                ((this.DataContext as StationNotEF).Id,
                startCancel.SelectedDate, endCancel.SelectedDate);
        }

        //обновление таблицы с добавленными поездами в расписании
        private void RefreshAddedSchedule()
        {
            scheduleClient.GetAddedScheduleAsync
                ((this.DataContext as StationNotEF).Id, AddedSchedulefrom.SelectedDate,
                AddedScheduleTo.SelectedDate);
        }

        #endregion

        #region ServiceReferences EventHandler

        private void scheduleClient_GetScheduleCompleted
            (object sender, GetScheduleCompletedEventArgs e)
        {
            if (e.Result.IsGood)
                ScheduleTable.ItemsSource = e.Result.Data;
        }

        private void scheduleClient_DeleteScheduleCompleted
            (object sender, DeleteScheduleCompletedEventArgs e)
        {
            if (e.Result)
                MessageBox.Show("Schedule is deleted");
            else
                MessageBox.Show("Schedule is not deleted");
            RefreshSchedule();
        }

        private void scheduleClient_GetLocationsCompleted
            (object sender, GetLocationsCompletedEventArgs e)
        {
            if (e.Result.IsGood)
                Location.ItemsSource = e.Result.Data;
            if (locationTemp != null)
                Location.SelectedValue = locationTemp.Id;
        }

        private void scheduleClient_SetCancelledScheduleCompleted
            (object sender, SetCancelledScheduleCompletedEventArgs e)
        {
            if (e.Result)
                MessageBox.Show("Schedule is cancelled");
            else
                MessageBox.Show("Schedule is not cancelled");

            if (ScheduleTable.SelectedIndex != -1)
                RefreshSchedule();
            else
                RefreshCancelSchedule();
        }

        private void scheduleClient_GetChangesScheduleCompleted
            (object sender, GetChangesScheduleCompletedEventArgs e)
        {
            if (e.Result.IsGood)
                ScheduleChangesTable.ItemsSource = e.Result.Data;
        }

        private void scheduleClient_GetCancelledScheduleCompleted
            (object sender, GetCancelledScheduleCompletedEventArgs e)
        {
            if (e.Result.IsGood)
                CancelScheduleTable.ItemsSource = e.Result.Data;
        }

        private void scheduleClient_AddScheduleCompleted
            (object sender, AddScheduleCompletedEventArgs e)
        {
            if (e.Result)
                MessageBox.Show("Schedule added");
            else
                MessageBox.Show("Schedule is not added");
            RefreshSchedule();
        }

        private void scheduleClient_AddScheduleChangeCompleted
            (object sender, AddScheduleChangeCompletedEventArgs e)
        {
            if (e.Result)
                MessageBox.Show("Schedule changes is added");
            else
                MessageBox.Show("Schedule changes is not added");
        }

        private void scheduleClient_ReplaceScheduleCompleted
            (object sender, ReplaceScheduleCompletedEventArgs e)
        {
            if (e.Result)
                MessageBox.Show("Schedule is replaced");
            else
                MessageBox.Show("Schedule is not replaced");
            RefreshSchedule();
        }

        private void scheduleClient_GetAddedScheduleCompleted
            (object seneder, GetAddedScheduleCompletedEventArgs e)
        {
            if (e.Result.IsGood)
                AddedScheduleTable.ItemsSource = e.Result.Data;
        }

        private void scheduleClient_ReplaceScheduleChangesCompleted
            (object sender, ReplaceScheduleChangesCompletedEventArgs e)
        {
            if (e.Result)
                MessageBox.Show("Schedule changes is replaced");
            else
                MessageBox.Show("Schedule changes is not replaced");

            if (ScheduleChangesTable.SelectedIndex != -1)
                RefreshChangesSchedule();
            else if (CancelScheduleTable.SelectedIndex != -1)
                RefreshCancelSchedule();
            else
                RefreshAddedSchedule();
        }

        private void scheduleClient_DeleteScheduleChangesCompleted
            (object seneder, DeleteScheduleChangesCompletedEventArgs e)
        {
            if (e.Result)
                MessageBox.Show("Schedule changes is deleted");
            else
                MessageBox.Show("Schedule changes is not deleted");
            if (ScheduleChangesTable.SelectedIndex != -1)
                RefreshChangesSchedule();
            else if (CancelScheduleTable.SelectedIndex != -1)
                RefreshCancelSchedule();
            else RefreshAddedSchedule();
        }

        #endregion

        #region ButtonClick EventHadler

        //показ панели для ввода данных для добавления расписания
        private void AddScheduleDialog_Click(object sender, RoutedEventArgs e)
        {
            ClearScheduleChanges("Add Schedule", DaysPanel);
            VisibilityButton(AddSchedule);
        }

        //показ панели для редактирования данных обычного расписания
        private void Edit_Click(object sender, RoutedEventArgs e)
        {
            VisibilityButton(EditSchedule);
            ScheduleChanges.Visibility = Visibility.Visible;
            HeaderChangesSchedule.Text = "Changes Schedule";
            FillScheduleChanges(ScheduleTable.SelectedItem as wScheduleNode);
            DaysPanelFalse();
            foreach (wDayOfWeek days in ((wScheduleNode)(ScheduleTable.SelectedItem)).DaysOfWeek)
            {
                if (days.Id == 2) Monday.IsChecked = true;
                if (days.Id == 3) Tuesday.IsChecked = true;
                if (days.Id == 4) Wednesday.IsChecked = true;
                if (days.Id == 5) Thursday.IsChecked = true;
                if (days.Id == 6) Friday.IsChecked = true;
                if (days.Id == 7) Saturday.IsChecked = true;
                if (days.Id == 1) Sunday.IsChecked = true;
            }
            CancelCheckBox.Visibility = Visibility.Collapsed;
            DateChanges.Visibility = Visibility.Collapsed;
            DaysPanel.Visibility = Visibility.Visible;
        }

        //удаление выделенной строки из расписания
        private void DelSchedule_Click(object sender, RoutedEventArgs e)
        {
            scheduleClient.DeleteScheduleAsync
                ((ScheduleTable.SelectedItem as wScheduleNode).Id);
        }

        //показ панели для ввода данных для добавления оперативного изменения 
        //на выделенный поезд в таблице с расписанием
        private void AddChanges_Click(object sender, RoutedEventArgs e)
        {
            ClearScheduleChanges("Add Changes Schedule", DateChanges, CancelCheckBox);
            FillScheduleChanges(ScheduleTable.SelectedItem as wScheduleNode);
            VisibilityButton(AddChangesSchedule);
        }

        //отмена оперативного изменения с отменой поезда
        private void UnCancel_Click(object sender, RoutedEventArgs e)
        {
            scheduleClient.SetCancelledScheduleAsync
               ((int)((CancelScheduleTable.SelectedItem as wScheduleChanxNode).ScheduleId),
               DateTime.Today, false);
        }

        //отмена поезда
        private void Cancel_Click(object sender, RoutedEventArgs e)
        {
            scheduleClient.SetCancelledScheduleAsync
                ((ScheduleTable.SelectedItem as wScheduleNode).Id, DateTime.Today, true);
        }

        //показ таблицы с отмененными поездами
        private void CancelSchedule_Click(object sender, RoutedEventArgs e)
        {
            VisibilityTable(CancelScheduleTablePanel);
            RefreshCancelSchedule();
        }

        //добавление оперативного изменения
        private void AddChangesSchedule_Click(object sender, RoutedEventArgs e)
        {
            wScheduleChanxNode addChangesSchedule = FillScheduleChanges();

            if (addChangesSchedule != null)
            {
                if (ScheduleTable.SelectedIndex != -1)
                {
                    addChangesSchedule.ScheduleId = (ScheduleTable.SelectedItem as wScheduleNode).Id;
                    addChangesSchedule.Canceled = (bool)CancelCheckBox.IsChecked;
                }
                else
                {
                    addChangesSchedule.ScheduleId = null;
                    addChangesSchedule.Canceled = false;
                }

                if (DateChanges.SelectedDate != null)
                    addChangesSchedule.DateOfChange = (DateTime)DateChanges.SelectedDate;
                else addChangesSchedule.DateOfChange = DateTime.Today;

                scheduleClient.AddScheduleChangeAsync(addChangesSchedule);
            }
        }

        //добавление поезда в расписание
        private void AddSchedule_Click(object sender, RoutedEventArgs e)
        {
            wScheduleNode tempSchedule = FillSchedule();
            if (tempSchedule != null)
                scheduleClient.AddScheduleAsync(tempSchedule);
        }

        //изменения данных о поезде в расписании
        private void EditSchedule_Click(object sender, RoutedEventArgs e)
        {
            wScheduleNode tempSchedule = FillSchedule();

            if (tempSchedule != null && ScheduleTable.SelectedIndex != -1)
                scheduleClient.ReplaceScheduleAsync(((wScheduleNode)
                    (ScheduleTable.SelectedItem)).Id, tempSchedule);
        }

        ///показ панели для ввода данных для добавления оперативного изменения        
        private void AddChangeScheduleDialog_Click(object sender, RoutedEventArgs e)
        {
            ClearScheduleChanges("Add Change Schedule", CancelCheckBox);
            VisibilityButton(AddChangesSchedule);
            DateChanges.Visibility = Visibility.Visible;
        }

        //показ таблицы с добавленными поездами (schedule_id=null)
        private void ShowAddedSchedule_Click(object sender, RoutedEventArgs e)
        {
            VisibilityTable(AddedScheduleTablePanel);
            RefreshAddedSchedule();
        }

        //показ таблицы с обычным расписанием
        private void ShowSchedule_Click(object sender, RoutedEventArgs e)
        {
            VisibilityTable(ScheduleTablePanel);
            RefreshSchedule();
        }

        //показ таблицы с изменениями в расписании
        private void SnowScheduleChanges_Click(object sender, RoutedEventArgs e)
        {
            VisibilityTable(ScheduleChangesTablePanel);
            RefreshChangesSchedule();
        }

        //удаление изменения в расписании
        private void DelChanges_Click(object sender, RoutedEventArgs e)
        {
            int delChanges;
            if (ScheduleChangesTable.SelectedIndex != -1)
                delChanges = ((wScheduleChanxNode)(ScheduleChangesTable.SelectedItem)).Id;
            else if (CancelScheduleTable.SelectedIndex != -1)
                delChanges = ((wScheduleChanxNode)(CancelScheduleTable.SelectedItem)).Id;
            else
                delChanges = ((wScheduleChanxNode)(AddedScheduleTable.SelectedItem)).Id;

            scheduleClient.DeleteScheduleChangesAsync(delChanges);
        }

        //показ панели с редактированием изменения в расписании
        private void EditChanges_Click(object sender, RoutedEventArgs e)
        {
            ScheduleChanges.Visibility = Visibility.Visible;
            VisibilityButton(EditChangesSchedule);
            HeaderChangesSchedule.Text = "Edit Change Schedule";
            wScheduleChanxNode editChanges = new wScheduleChanxNode();

            if (ScheduleChangesTable.SelectedIndex != -1) editChanges =
                (wScheduleChanxNode)(ScheduleChangesTable.SelectedItem);
            else if (CancelScheduleTable.SelectedIndex != -1) editChanges =
                (wScheduleChanxNode)(CancelScheduleTable.SelectedItem);
            else editChanges = (wScheduleChanxNode)(AddedScheduleTable.SelectedItem);

            NumberOfTransport.Text = editChanges.NumberOfTransport;
            StationOfDestination.Text = editChanges.StationOfDestination;
            TimeOfDepartureHours.Text = editChanges.TimeOfDeparture.Hours.ToString();
            TimeOfDepartureMinutes.Text = editChanges.TimeOfDeparture.Minutes.ToString();
            TimeOfLandingHours.Text = editChanges.TimeOfLanding.Hours.ToString();
            TimeOfLandingMinutes.Text = editChanges.TimeOfLanding.Minutes.ToString();
            DateChanges.SelectedDate = editChanges.DateOfChange;
            FillLocationsCombobox(editChanges.Location);

            CancelCheckBox.Visibility = Visibility.Visible;
            DateChanges.Visibility = Visibility.Visible;
            CancelCheckBox.IsChecked = editChanges.Canceled;
            DaysPanel.Visibility = Visibility.Collapsed;
        }

        //редактирование изменения
        private void EditChangesSchedule_Click(object sender, RoutedEventArgs e)
        {
            wScheduleChanxNode editChangesSchedule = FillScheduleChanges();
            if (editChangesSchedule != null)
            {
                editChangesSchedule.Canceled = (bool)CancelCheckBox.IsChecked;

                int? ScheduleID = null;
                if (ScheduleChangesTable.SelectedIndex != -1)
                    ScheduleID = ((wScheduleChanxNode)(ScheduleChangesTable.SelectedItem)).ScheduleId;
                else if (AddedScheduleTable.SelectedIndex != -1)
                    ScheduleID = ((wScheduleChanxNode)(AddedScheduleTable.SelectedItem)).ScheduleId;
                else if (CancelScheduleTable.SelectedIndex != -1)
                    ScheduleID = ((wScheduleChanxNode)(CancelScheduleTable.SelectedItem)).ScheduleId;
                else editChangesSchedule.Canceled = false;

                int scheduleChangesId;
                if (ScheduleChangesTable.SelectedIndex != -1)
                    scheduleChangesId = ((wScheduleChanxNode)(ScheduleChangesTable.SelectedItem)).Id;
                else if (CancelScheduleTable.SelectedIndex != -1)
                    scheduleChangesId = ((wScheduleChanxNode)(CancelScheduleTable.SelectedItem)).Id;
                else scheduleChangesId = ((wScheduleChanxNode)(AddedScheduleTable.SelectedItem)).Id;

                editChangesSchedule.ScheduleId = ScheduleID;
                if (DateChanges.SelectedDate == null)
                {
                    editChangesSchedule.DateOfChange = DateTime.Today;
                }
                else editChangesSchedule.DateOfChange = (DateTime)DateChanges.SelectedDate;

                scheduleClient.ReplaceScheduleChangesAsync(scheduleChangesId, editChangesSchedule);
            }
        }

        #endregion

        #region Other methods

        //созданием объекта класса wScheduleChanxNode по введенным данным
        private wScheduleChanxNode FillScheduleChanges()
        {
            wScheduleChanxNode editChangesSchedule = new wScheduleChanxNode();

            TimeSpan timeOfDeparture = new TimeSpan();
            TimeSpan timeOfLanding = new TimeSpan();

            string strTimeOfDeparture = TimeOfDepartureHours.Text + ":" + TimeOfDepartureMinutes.Text + ":0";
            string strTimeOfLanding = TimeOfLandingHours.Text + ":" + TimeOfLandingMinutes.Text + ":0";

            if (TimeSpan.TryParse(strTimeOfDeparture, out timeOfDeparture) &&
                TimeSpan.TryParse(strTimeOfLanding, out timeOfLanding)
                && Location.SelectedIndex != -1 && NumberOfTransport.Text != "" &&
                StationOfDestination.Text != "")
            {
                editChangesSchedule.NumberOfTransport = NumberOfTransport.Text;
                editChangesSchedule.TimeOfDeparture = timeOfDeparture;
                editChangesSchedule.TimeOfLanding = timeOfLanding;
                editChangesSchedule.StationOfDestination = StationOfDestination.Text;
                editChangesSchedule.LocationId = ((wLocation)(Location.SelectedItem)).Id;
            }
            else editChangesSchedule = null;

            return editChangesSchedule;
        }

        //созданием объекта класса wScheduleNode по введенным данным
        private wScheduleNode FillSchedule()
        {
            wScheduleNode tempSchedule = new wScheduleNode();

            TimeSpan timeOfDeparture = new TimeSpan();
            TimeSpan timeOfLanding = new TimeSpan();

            string strTimeOfDeparture = TimeOfDepartureHours.Text + ":" + TimeOfDepartureMinutes.Text + ":0";
            string strTimeOfLanding = TimeOfLandingHours.Text + ":" + TimeOfLandingMinutes.Text + ":0";

            if (TimeSpan.TryParse(strTimeOfDeparture, out timeOfDeparture) &&
                TimeSpan.TryParse(strTimeOfLanding, out timeOfLanding)
                && Location.SelectedIndex != -1 && NumberOfTransport.Text != "" &&
                StationOfDestination.Text != "")
            {
                tempSchedule.NumberOfTransport = NumberOfTransport.Text;
                tempSchedule.TimeOfDeparture = timeOfDeparture;
                tempSchedule.TimeOfLanding = timeOfLanding;
                tempSchedule.StationOfDestination = StationOfDestination.Text;
                tempSchedule.LocationId = (Location.SelectedItem as wLocation).Id;
                tempSchedule.DaysOfWeek = FillDaysOfWeekPanel();
            }
            else tempSchedule = null;

            return tempSchedule;
        }

        //создание списка с выделенными днями недели
        private ObservableCollection<wDayOfWeek> FillDaysOfWeekPanel()
        {
            // создаем список дней недели, воскресенье id=1, понедельник id=2 и т.д.
            ObservableCollection<wDayOfWeek> tempDayOfWeek = new ObservableCollection<wDayOfWeek>();
            if ((bool)Monday.IsChecked) tempDayOfWeek.Add(new wDayOfWeek() { Id = 2 });
            if ((bool)Tuesday.IsChecked) tempDayOfWeek.Add(new wDayOfWeek() { Id = 3 });
            if ((bool)Wednesday.IsChecked) tempDayOfWeek.Add(new wDayOfWeek() { Id = 4 });
            if ((bool)Thursday.IsChecked) tempDayOfWeek.Add(new wDayOfWeek() { Id = 5 });
            if ((bool)Friday.IsChecked) tempDayOfWeek.Add(new wDayOfWeek() { Id = 6 });
            if ((bool)Saturday.IsChecked) tempDayOfWeek.Add(new wDayOfWeek() { Id = 7 });
            if ((bool)Sunday.IsChecked) tempDayOfWeek.Add(new wDayOfWeek() { Id = 1 });

            return tempDayOfWeek;
        }

        //делается видимой необходимая таблица
        private void VisibilityTable(UIElement table)
        {
            ScheduleTablePanel.Visibility = Visibility.Collapsed;
            ScheduleChangesTablePanel.Visibility = Visibility.Collapsed;
            CancelScheduleTablePanel.Visibility = Visibility.Collapsed;
            AddedScheduleTablePanel.Visibility = Visibility.Collapsed;
            table.Visibility = Visibility.Visible;
        }

        //делается видимой необходимая кнопка        
        private void VisibilityButton(UIElement button)
        {
            AddSchedule.Visibility = Visibility.Collapsed;
            AddChangesSchedule.Visibility = Visibility.Collapsed;
            EditSchedule.Visibility = Visibility.Collapsed;
            EditChangesSchedule.Visibility = Visibility.Collapsed;
            button.Visibility = Visibility.Visible;
        }

        //очистка поставленных галочек в панеле с днями недели
        private void DaysPanelFalse()
        {
            Monday.IsChecked = false;
            Tuesday.IsChecked = false;
            Wednesday.IsChecked = false;
            Thursday.IsChecked = false;
            Friday.IsChecked = false;
            Saturday.IsChecked = false;
            Sunday.IsChecked = false;
        }

        //заполнение списка мест
        private void FillLocationsCombobox(wLocation location = null)
        {
            locationTemp = location;
            if (this.DataContext != null)
                scheduleClient.GetLocationsAsync((this.DataContext as StationNotEF).Id);
        }

        //заполение панели изменения в расписании данными
        private void FillScheduleChanges(wScheduleNode schedule)
        {
            NumberOfTransport.Text = schedule.NumberOfTransport;
            StationOfDestination.Text = schedule.StationOfDestination;
            TimeOfDepartureHours.Text = schedule.TimeOfDeparture.Hours.ToString();
            TimeOfDepartureMinutes.Text = schedule.TimeOfDeparture.Minutes.ToString();
            TimeOfLandingHours.Text = schedule.TimeOfLanding.Hours.ToString();
            TimeOfLandingMinutes.Text = schedule.TimeOfLanding.Minutes.ToString();
            FillLocationsCombobox(schedule.Location);
        }

        //очистка полей в панели изменения в расписании
        private void ClearScheduleChanges(string header, UIElement element1 = null, UIElement element2 = null)
        {
            ScheduleChanges.Visibility = Visibility.Visible;
            HeaderChangesSchedule.Text = header;
            NumberOfTransport.Text = "";
            StationOfDestination.Text = "";
            TimeOfDepartureHours.Text = "";
            TimeOfDepartureMinutes.Text = "";
            TimeOfLandingHours.Text = "";
            TimeOfLandingMinutes.Text = "";
            FillLocationsCombobox();
            CancelCheckBox.Visibility = Visibility.Collapsed;
            CancelCheckBox.IsChecked = false;
            DateChanges.Visibility = Visibility.Collapsed;
            DateChanges.SelectedDate = null;
            DaysPanel.Visibility = Visibility.Collapsed;
            DaysPanelFalse();
            if (element1 != null)
                element1.Visibility = Visibility.Visible;
            if (element2 != null)
                element2.Visibility = Visibility.Visible;
        }

        #endregion
    }
}